﻿using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Web;
using System.Web.Script.Serialization;

namespace heyirunde
{
    public class JsonHelper
    {
        /// <summary>
        /// 获取某一天是这一年的第几周      第 "+ WeekOfYear(DateTime.Now, new CultureInfo("zh-CN")).ToString()+" 周";
        /// </summary>
        /// <param name="dt"></param>
        /// <param name="ci"></param>
        /// <returns></returns>
        public int WeekOfYear(DateTime dt, CultureInfo ci)
        {
            return ci.Calendar.GetWeekOfYear(dt, ci.DateTimeFormat.CalendarWeekRule, ci.DateTimeFormat.FirstDayOfWeek);
        }

        /// <summary>
        /// 获取一年中的周
        /// </summary>
        /// <param name="dt">日期</param>
        /// <returns></returns>
        public static int GetWeekOfYear(DateTime dt)
        {
            System.Globalization.GregorianCalendar gc = new System.Globalization.GregorianCalendar();
            int weekOfYear = gc.GetWeekOfYear(dt, System.Globalization.CalendarWeekRule.FirstDay, DayOfWeek.Monday);

            return weekOfYear;
        }


        /// <summary>
        /// 根据一年中的第几周获取该周的开始日期与结束日期
        /// </summary>
        /// <param name="year"></param>
        /// <param name="weekNumber"></param>
        /// <param name="culture"></param>
        /// <returns></returns>
        public static Tuple<DateTime, DateTime> GetFirstEndDayOfWeek(int year, int weekNumber, System.Globalization.CultureInfo culture)
        {
            System.Globalization.Calendar calendar = culture.Calendar;
            DateTime firstOfYear = new DateTime(year, 1, 1, calendar);
            DateTime targetDay = calendar.AddWeeks(firstOfYear, weekNumber - 1);
            DayOfWeek firstDayOfWeek = culture.DateTimeFormat.FirstDayOfWeek;

            while (targetDay.DayOfWeek != firstDayOfWeek)
            {
                targetDay = targetDay.AddDays(-1);
            }

            return Tuple.Create<DateTime, DateTime>(targetDay, targetDay.AddDays(6));
        }


        /// <summary>
        /// 将字符串转成 json
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="json"></param>
        /// <returns></returns>
        public static T DeserializeJsonToObject<T>(string json) where T : class
        {
            JsonSerializer serializer = new JsonSerializer();
            StringReader sr = new StringReader(json);
            object o = serializer.Deserialize(new JsonTextReader(sr), typeof(T));
            T t = o as T;
            return t;
        }

        public static string ImageUrl = ConfigurationManager.AppSettings["ImageUrl"];

        /// <summary>
        /// json传输函数
        /// </summary>
        /// <param name="personArray"></param>
        /// <returns></returns>
        public string JsonClass(PersonArray personArray)
        {
            StringWriter sw;
            JsonSerializer serializer = new JsonSerializer();
            sw = new StringWriter();
            serializer.Serialize(new JsonTextWriter(sw), personArray);
            return sw.GetStringBuilder().ToString();

        }

        public string ObjToJson(Object obj)
        {
            StringWriter sw;
            JsonSerializer serializer = new JsonSerializer();
            sw = new StringWriter();
            serializer.Serialize(new JsonTextWriter(sw), obj);
            return sw.GetStringBuilder().ToString();
        }

        //去除字段后的空格或返回空字符串
        public string trimField(object s)
        {
            if (s == null)
            {
                return "";
            }
            else
            {
                return s.ToString().Trim();

            }
        }

        /// <summary>
        /// 转为日期时间字符串
        /// </summary>
        /// <param name="dt"></param>
        /// <returns></returns>
        public string ToDateTime(DateTime dt)
        {
            return dt.ToString("yyyy-MM-dd HH:mm:ss");
        }

        /// <summary>
        /// 转为日期
        /// </summary>
        /// <param name="dt"></param>
        /// <returns></returns>
        public string ToDate(DateTime dt)
        {
            return dt.ToString("yyyy-MM-dd");
        }

        /// <summary>
        /// 判断是否是数字
        /// </summary>
        /// <param name="parameter"></param>
        /// <returns></returns>
        public bool IsNumber(string[] parameter)
        {
            const string pattern = @"^(-?\d+)(\.\d+)?$";
            //正则表达式
            Regex rx = new Regex(pattern, RegexOptions.None);

            for (int i = 0; i < parameter.Length; i++)
            {
                var b = parameter[i];
                var bo = rx.IsMatch(parameter[i]);
                if (!rx.IsMatch(parameter[i]))
                {
                    return false;
                }

            }

            return true;
        }

        /// <summary>
        /// 获取集合的交集
        /// </summary>
        /// <param name="arr0"></param>
        /// <param name="arr1"></param>
        /// <returns></returns>
        public static List<string> GetIntersct(List<string> arr0, List<string> arr1)
        {
            Dictionary<string, int> dicIntersect = new Dictionary<string, int>();
            List<string> intersectData = new List<string>();

            //遍历第一个集合
            foreach (var data in arr0)
            {
                if (!dicIntersect.Keys.Contains(data))
                {
                    dicIntersect.Add(data, 0);
                }
                dicIntersect[data]++;
            }


            //遍历第二个集合
            foreach (var data in arr1)
            {
                if (!dicIntersect.Keys.Contains(data))
                {
                    dicIntersect.Add(data, 0);
                }
                dicIntersect[data]++;
            }


            foreach (var intData in dicIntersect)
            {
                if (intData.Value > 1)
                {
                    intersectData.Add(intData.Key);
                }
            }

            return intersectData;

        }


        /// <summary>
        /// 对象转换为json字符串
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static string ToJSON(object obj)
        {
            StringBuilder sb = new StringBuilder();
            JavaScriptSerializer json = new JavaScriptSerializer();
            json.Serialize(obj, sb);
            return sb.ToString();
        }


        /// <summary>
        /// Json字符串转内存对象
        /// </summary>
        /// <param name="jsonString"></param>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static T FromJSON<T>(string jsonString)
        {
            JavaScriptSerializer json = new JavaScriptSerializer();
            return json.Deserialize<T>(jsonString);
        }


        /// <summary>
        /// 对象转换为字典
        /// **
        /// </summary>
        /// <param name="obj">待转化的对象</param>
        /// <param name="isIgnoreNull">是否忽略NULL 这里我不需要转化NULL的值，正常使用可以不传参数 默认全转换</param>
        /// <returns></returns>
        public static Dictionary<string, object> ObjectToMap(object obj, bool isIgnoreNull = false)
        {
            Dictionary<string, object> map = new Dictionary<string, object>();

            Type t = obj.GetType(); // 获取对象对应的类， 对应的类型

            PropertyInfo[] pi = t.GetProperties(BindingFlags.Public | BindingFlags.Instance); // 获取当前type公共属性

            foreach (PropertyInfo p in pi)
            {
                MethodInfo m = p.GetGetMethod();

                if (m != null && m.IsPublic)
                {
                    // 进行判NULL处理 
                    if (m.Invoke(obj, new object[] { }) != null || !isIgnoreNull) //使用指定参数调用由当前实例表示的方法或构造函数。
                    {
                        map.Add(p.Name, m.Invoke(obj, new object[] { })); // 向字典添加元素
                    }
                }
            }


            return map;
        }

        /// <summary>
        /// 对实体类的字符串trim
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="isIgnoreNull"></param>
        public static T ObjToTrim<T>(T obj, bool isIgnoreNull = false) where T : class, new()
        {
            //Dictionary<string, object> dictionary = new Dictionary<string, object>();
            Type type = obj.GetType(); // 获取对象对应的类， 对应的类型

            T instance = new T();

            JsonHelper json = new JsonHelper();

            //// 获取当前type公共属性
            PropertyInfo[] pi = type.GetProperties(BindingFlags.Public | BindingFlags.Instance);
            foreach (PropertyInfo p in pi)
            {
                MethodInfo mi = p.GetGetMethod();
                if (mi != null && mi.IsPublic)
                {
                    string name = p.Name;
                    var value = mi.Invoke(obj, new object[] { });
                    if (p.PropertyType.Name == "String")
                    {
                        value = json.trimField(value);
                    }

                    // 进行判NULL处理 
                    if (value != null || !isIgnoreNull) //使用指定参数调用由当前实例表示的方法或构造函数。
                    {
                        //dictionary.Add(p.Name, value); // 向字典添加元素
                        instance.GetType().GetProperty(name).SetValue(instance, value);
                    }
                }

            }

            return instance;

        }
        /// <summary>
        /// 返回结果
        /// </summary>
        public class PersonArray : Person
        {
            public Object items { get; set; }

        }
        public class Person
        {
            #region json状态位
            /// <summary>
            /// json状态位
            /// </summary>
            public int status { set; get; }
            #endregion

            #region json信息符
            /// <summary>
            /// json信息符
            /// </summary>
            public string msg { set; get; }
            #endregion
            #region 备注信息
            /// <summary>
            /// 备注信息
            /// </summary>
            public string remark { set; get; }
            #endregion
        }
    }
}